package com.skivingcloud.admin.sys.service.impl;

import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.skivingcloud.admin.constants.Constant;
import com.skivingcloud.admin.security.UserUtil;
import com.skivingcloud.admin.sys.entity.*;
import com.skivingcloud.admin.sys.mapper.SysDashboardSettingMapper;
import com.skivingcloud.admin.sys.mapper.SysOrgMapper;
import com.skivingcloud.admin.sys.service.SysDashboardSettingService;
import com.skivingcloud.common.exceptions.BusinessException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.skivingcloud.common.utils.PageParameter;

import java.util.List;

/**
 * 首页看板设置 服务层实现。
 *
 * @author skivingcloud
 * @since 2024-09-03
 */
@Service
public class SysDashboardSettingServiceImpl extends ServiceImpl<SysDashboardSettingMapper, SysDashboardSetting> implements SysDashboardSettingService {

    private SysOrgMapper sysOrgMapper;

    public SysDashboardSettingServiceImpl(SysOrgMapper sysOrgMapper) {
        this.sysOrgMapper = sysOrgMapper;
    }

    /**
     * 分页查询首页看板设置
     *
     * @param parameter 查询参数
     * @return 分页查询结果
     */
    @Override
    public Page<SysDashboardSetting> queryByPage(PageParameter<SysDashboardSetting> parameter){
        Page<SysDashboardSetting> page = new Page<>(parameter.getPage(), parameter.getPageSize());
        QueryWrapper queryWrapper = QueryWrapper.create().from(SysDashboardSetting.class).as("ds");
        if (parameter.getParam() == null || StringUtils.isBlank(parameter.getParam().getType())) {
            throw new BusinessException("请选择类型");
        }
        //查询条件
        queryWrapper.and(SysDashboardSetting::getType).eq(parameter.getParam().getType());
        if (StringUtils.isNoneBlank(parameter.getParam().getDashboardId())) {
            queryWrapper.and(SysDashboardSetting::getDashboardId).eq(parameter.getParam().getDashboardId());
        }

        switch (parameter.getParam().getType()){
            case Constant.DASHBOARD_SET_TYPE_USER -> {
                queryWrapper.join(SysUser.class).as("u").on(
                        wrapper -> wrapper.where(SysDashboardSetting::getTypeId).eq(SysUser::getId)
                );
                if (StringUtils.isNoneBlank(parameter.getParam().getTypeId())) {
                    queryWrapper.and(SysUser::getStaffName).like(parameter.getParam().getTypeId());
                }
            }
            case Constant.DASHBOARD_SET_TYPE_STATION -> {
                queryWrapper.join(SysStation.class).as("s").on(
                        wrapper -> wrapper.where(SysDashboardSetting::getTypeId).eq(SysStation::getId)
                );
                if (StringUtils.isNoneBlank(parameter.getParam().getTypeId())) {
                    queryWrapper.and(SysStation::getStationName).like(parameter.getParam().getTypeId());
                }
            }
            case Constant.DASHBOARD_SET_TYPE_ROLE -> {
                queryWrapper.join(SysRole.class).as("r").on(
                        wrapper -> wrapper.where(SysDashboardSetting::getTypeId).eq(SysRole::getId)
                );
                if (StringUtils.isNoneBlank(parameter.getParam().getTypeId())) {
                    queryWrapper.and(SysRole::getRoleName).like(parameter.getParam().getTypeId());
                }
            }
            case Constant.DASHBOARD_SET_TYPE_ORG -> {
                queryWrapper.join(SysOrg.class).as("o").on(
                        wrapper -> wrapper.where(SysDashboardSetting::getTypeId).eq(SysOrg::getId)
                );
                if (StringUtils.isNoneBlank(parameter.getParam().getTypeId())) {
                    queryWrapper.and(SysOrg::getOrgName).like(parameter.getParam().getTypeId());
                }
            }
        }

        if (StringUtils.isNoneBlank(parameter.getParam().getCreateUser())) {
            queryWrapper.and(SysDashboardSetting::getCreateUser).like(parameter.getParam().getCreateUser());
        }
        if (StringUtils.isNoneBlank(parameter.getParam().getModUser())) {
            queryWrapper.and(SysDashboardSetting::getModUser).like(parameter.getParam().getModUser());
        }
        queryWrapper.and(SysDashboardSetting::getTenantId).eq(UserUtil.getCurrentUser().getTenantId());
        queryWrapper.orderBy(SysDashboardSetting::getCreateTime).desc();
        return this.page(page, queryWrapper);
    }

    @Override
    public String getDashboardSettingByUserId(String userId) {
        List<SysDashboardSetting> list = this.list(
                QueryWrapper.create().eq(SysDashboardSetting::getType, Constant.DASHBOARD_SET_TYPE_USER)
                        .and(SysDashboardSetting::getTypeId).eq(userId)
        );
        if (!list.isEmpty()) {
            return list.get(0).getDashboardId();
        }
        list = this.list(
                QueryWrapper.create().from(SysDashboardSetting.class).as("d")
                        .join(SysUserStation.class).as("s").on(
                                wrapper -> wrapper.where(SysDashboardSetting::getTypeId).eq(SysUserStation::getStationId)
                        ).and(SysDashboardSetting::getType).eq(Constant.DASHBOARD_SET_TYPE_STATION)
                        .and(SysUserStation::getUserId).eq(userId)
        );
        if (!list.isEmpty()) {
            return list.get(0).getDashboardId();
        }
        list = this.list(
                QueryWrapper.create().from(SysDashboardSetting.class).as("d")
                        .join(SysUserRole.class).as("r").on(
                                wrapper -> wrapper.where(SysDashboardSetting::getTypeId).eq(SysUserRole::getRoleId)
                        ).and(SysDashboardSetting::getType).eq(Constant.DASHBOARD_SET_TYPE_ROLE)
                        .and(SysUserRole::getUserId).eq(userId)
        );
        if (!list.isEmpty()) {
            return list.get(0).getDashboardId();
        }
        List<SysOrg> orgList = sysOrgMapper.selectUserOrgListUp(userId);
        list = this.list(
                QueryWrapper.create().where(SysDashboardSetting::getType).eq(Constant.DASHBOARD_SET_TYPE_ORG)
                        .and(SysDashboardSetting::getTypeId).in(orgList.stream().map(SysOrg::getId).toList())
        );
        if (!list.isEmpty()) {
            return list.get(0).getDashboardId();
        }
        return "";
    }
}
